﻿using Magicodes.Logger;
using Magicodes.WeChat.SDK;
using Magicodes.WeChat.SDK.Apis.TemplateMessage;
using Magicodes.WeiChat.Infrastructure.Expressions;
using Magicodes.WeiChat.Unity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Magicodes.WeiChat.Infrastructure.Events
{
    /// <summary>
    /// 事件管理器
    /// </summary>
    public class EventManager : ThreadSafeLazyBaseSingleton<EventManager>
    {
        /// <summary>
        /// 日志记录器
        /// </summary>
        public LoggerBase Logger { get; set; } = new NullLogger("EventManager");

        /// <summary>
        /// 事件触发
        /// </summary>
        /// <typeparam name="TEventData">事件数据类型</typeparam>
        /// <param name="name">事件名称(不填则自动匹配)</param>
        /// <param name="data">事件数据</param>
        public void Trigger<TEventData>(TEventData data, string name = null) where TEventData : IEventData
        {
            //获取已启用的监听器
            var items = GetEnabledListeners();
            if (items == null)
            {
                return;
            }
            //获取事件侦听器名称
            name = string.IsNullOrWhiteSpace(name) ? typeof(TEventData).FullName : name;
            var eventListener = items.FirstOrDefault(p => p.Name == name);
            if (eventListener != null)
            {
                //获取侦听器触发的操作
                if (eventListener.Actions != null && eventListener.Actions.Count > 0)
                {
                    //遍历所有操作
                    foreach (var action in eventListener.Actions)
                    {
                        //模板消息操作
                        if (action is MessagesTemplateAction)
                        {
                            var tAction = action as MessagesTemplateAction;
                            ExecuteMessagesTemplateAction(data, tAction);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 执行模板消息操作
        /// </summary>
        /// <typeparam name="TEventData"></typeparam>
        /// <param name="data"></param>
        /// <param name="tAction"></param>
        private void ExecuteMessagesTemplateAction<TEventData>(TEventData data, MessagesTemplateAction tAction) where TEventData : IEventData
        {
            //TODO:1)完成后台异步执行封装;2)异常体系封装

            try
            {
                //模板Id
                Logger.Log(LoggerLevels.Debug, "MessagesTemplateId:" + tAction.MessagesTemplateId + "\n");
                //接收者
                var receivers = ExpressionsHelper.ExecuteEvalString(tAction.Receivers, data);
                Logger.Log(LoggerLevels.Debug, "Receivers:" + receivers + "\n");
                //详情链接
                var url = ExpressionsHelper.ExecuteEvalString(tAction.Url, data);
                Logger.Log(LoggerLevels.Debug, "Url:" + url + "\n");
                var tmodel = new TemplateMessageCreateModel()
                {
                    MessagesTemplateNo = tAction.MessagesTemplateId,
                    ReceiverIds = receivers,
                    Url = url,
                    Data = new Dictionary<string, TemplateDataItem>()
                };
                foreach (var item in tAction.Items)
                {
                    //模板key的值
                    var dataValue = ExpressionsHelper.ExecuteEvalString(item.Value.Expression, data);
                    tmodel.Data.Add(item.Key, new TemplateDataItem(dataValue, item.Value.Color ?? "#173177"));
                    Logger.Log(LoggerLevels.Debug, item.Key + ":" + dataValue + "\n");
                }
                //推送模板消息
                WeChatApisContext.Current.TemplateMessageApi.Create(tmodel);
            }
            catch (Exception ex)
            {
                Logger.Log(LoggerLevels.Error, "模板消息发送失败", ex);
            }
        }

        /// <summary>
        /// 侦听器列表
        /// </summary>
        public List<EventListener> Listeners { get; set; } = new List<EventListener>();

        /// <summary>
        /// 获取已启用侦听器
        /// </summary>
        /// <returns></returns>
        public List<EventListener> GetEnabledListeners()
        {
            if (Listeners == null)
            {
                return null;
            }
            return Listeners.Where(p => p.Enabled).ToList();
        }
    }
}
